package com.feishi.core.media.javacv;

import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.DoublePointer;
import org.bytedeco.javacpp.opencv_core;

import static org.bytedeco.javacpp.opencv_core.*;
//import org.bytedeco.javacpp.opencv_core.Mat;
//import org.bytedeco.javacpp.opencv_core.Size;

import static org.bytedeco.javacpp.opencv_core.CV_8U;
import static org.bytedeco.javacpp.opencv_imgcodecs.imread;
import static org.bytedeco.javacpp.opencv_imgcodecs.imwrite;
import static org.bytedeco.javacpp.opencv_imgproc.*;

/**
 * @version 1.0
 * @auth caixq
 * @time 18-6-1 10:00
 **/
public class A {
    public static void main(String[] args) {
        Mat mat = imread("/home/caixq/Desktop/test.png");
        Mat gray = new Mat();
        cvtColor(mat, gray, COLOR_BGR2GRAY);
//        mat=gray;
        Mat out1=new Mat();
        Mat out2=new Mat();

            threshold(mat, out1, 170, 255, THRESH_BINARY);
            imwrite("/home/caixq/Desktop/test1.png",out1);
            Mat kernel_erode = getStructuringElement(MORPH_RECT, new Size(3, 3));
            erode(out1, out2, kernel_erode);
            imwrite("/home/caixq/Desktop/test2.png",out1);
//        for (int i = 0; i < 254; i++) {
//            threshold(mat, out1, i, 255, THRESH_BINARY);
//            imwrite("/tmp/out/out"+i+".png",out1);
////        System.out.println(size);
//            //4.腐蚀
////            for (int j = 0; j <=8; j++) {
////                Mat kernel_erode = getStructuringElement(MORPH_RECT, new Size(j+2, j+2));
////                erode(out1, out2, kernel_erode);
////                imwrite("/tmp/out/out"+i+"_"+j+".png",out1);
////            }
//
//        }
        Scalar c = mean(gray);
        Scalar c1 = c;

        segmentText(mat);

    }

    private static void segmentText(Mat spineImage) {
        Mat spineGray=new Mat();
        cvtColor(spineImage, spineGray, CV_BGR2GRAY);
//        gray.reserve((long) 0.5);
        Mat spineAhe=new Mat();
//        adaptiveThreshold(spineGray, spineAhe, 0.01);
        adaptiveHistEqual(spineGray, spineAhe, 0.01);
        imwrite("/home/caixq/Desktop/test1.png",spineGray);
        imwrite("/home/caixq/Desktop/test2.png",spineAhe);
//        Mat spine_th = Mat.zeros(spineGray.size(), CV_8U);
        MatExpr spine_th = Mat.zeros(spineGray.size(), CV_8U);


        int window_num = 40;

        double window_h = (spineImage.rows() / (double)window_num + 1e-3);

        int window_w = spineImage.cols();




        for (int i = 0; i < window_num; i ++) {
            double cut_from_r = window_h * i;
            double cut_to_r = window_h * (i+1);
            MatExpr window_img=  Mat.zeros(new Size((int) (cut_to_r-cut_from_r + 1), window_w), CV_8U);

            Rect rect = new Rect(0, (int)cut_from_r, window_w-1, (int)(cut_to_r - cut_from_r + 1));
            Mat img = new Mat(spineGray, rect);

            imwrite("/home/caixq/Desktop/test2_"+i+".png",img);

//            sharpenImage(window_img, window_img);
//            imshow("sharpen", window_img);
//        waitKey();
//        WriteData("/Users/eternity/Desktop/未命名文件夹/gray4.txt", window_img);
            double max_local = 0,min_local = 0;
//            minMaxLoc(window_img, &min_local, &max_local);
            DoublePointer doublePointer=new DoublePointer();
            minMaxLoc(window_img.asMat(),doublePointer);
            double color_diff = max_local - min_local;
////            doublePointer.
//            double thresh;
//            Mat window_tmp;
//            if (color_diff > 50)
//                thresh = threshold(window_img.a(), window_tmp, 1, 255, THRESH_OTSU);
//            else
//                thresh = 0;
//        cout<<thresh<<endl;
//            Mat seg_window=new Mat(window_img.size(), CV_64F);
//            imgQuantize(window_img, seg_window, thresh);
//        WriteData("/Users/eternity/Desktop/未命名文件夹/quantize2.txt", seg_window);
//            seg_window = seg_window == 1;
//        seg_window = seg_window / 255;
            //处理0边界值
//            vector<int> cols1,cols2,rows1,rows2;
//            findKEdgeFirst(seg_window, 0, 5, rows1, cols1);
//            findKEdgeLast (seg_window, 0, 5, rows2, cols2);
//            float max_zero_dist, max_one_dist;
//            if(cols1.empty() || cols2.empty())
//                max_zero_dist = 0.0;
//            else{
//                float avg_right = (rows2[0]+rows2[1]+rows2[2]+rows2[3]+rows2[4]) / (float)sizeof(rows2);
//                float avg_left  = (rows1[0]+rows1[1]+rows1[2]+rows1[3]+rows1[4]) / (float)sizeof(rows1);
//                max_zero_dist = avg_right - avg_left;
//            }
//            cols1.clear();
//            cols2.clear();
//            rows1.clear();
//            rows2.clear();
//
//            //处理1边界值
//            findKEdgeFirst(seg_window, 255, 5, rows1, cols1);
//            findKEdgeLast (seg_window, 255, 5, rows2, cols2);
//            if(cols1.empty() || cols2.empty())
//                max_one_dist = 0;
//            else{
//                float avg_right = (rows2[0]+rows2[1]+rows2[2]+rows2[3]+rows2[4]) / (float)sizeof(rows2);
//                float avg_left  = (rows1[0]+rows1[1]+rows1[2]+rows1[3]+rows1[4]) / (float)sizeof(rows1);
//                max_one_dist = avg_right - avg_left;
//            }
//            cols1.clear();
//            cols2.clear();
//            rows1.clear();
//            rows2.clear();
//
//            cv::Mat idx;
//            findNonZero(seg_window, idx);
//            int one_count = (int)idx.total();
//            int zero_count = (int)seg_window.total() - one_count;
//
//            float one_zero_diff = max_one_dist - max_zero_dist;
//            float  dist_limit = 5;
//
//            if(one_zero_diff > dist_limit)
//                seg_window = ~ seg_window;
//            else{
//                if(one_zero_diff > -dist_limit && one_count > zero_count)
//                    seg_window = ~ seg_window;
//            }
//
//            seg_window.copyTo(cv::Mat( spine_th, rect));
//        imshow("spine_th", spine_th);
//        waitKey();


        }
    }

    private static void imgQuantize(MatExpr s, Mat dst, double level) {
        Mat src=s.asMat();
        for (int i = 0; i < src.rows(); i ++) {
            BytePointer data = src.ptr(i);
            BytePointer data2 = dst.ptr(i);
            for (int j = 0; j < src.cols(); j ++) {
                if(data.get(j) <= level)
                    data2.put(j, (byte) 1);
                else
                    data2.put(j, (byte) 2);

            }
        }

    }

    private static void adaptiveHistEqual(Mat src, Mat dst, double clipLimit) {
        CLAHE clahe = createCLAHE();
        clahe.setClipLimit(clipLimit);
        clahe.apply(src, dst);
    }
}
